<template>
  <div class="mini-calendar" v-if="visible" ref="calendarRef" @click.stop>
    <div class="mini-calendar-header">
      <button @click="handlePrevMonth" class="nav-button">
        <i class="iconfont icon-arrow-left"></i>
      </button>
      <span>{{ currentMonthYear }}</span>
      <button @click="handleNextMonth" class="nav-button">
        <i class="iconfont icon-arrow-right"></i>
      </button>
    </div>
    
    <div class="mini-calendar-grid">
      <div class="mini-day-header" v-for="day in ['日', '一', '二', '三', '四', '五', '六']" :key="day">
        {{ day }}
      </div>
      <div
        v-for="day in calendarDays"
        :key="day.date"
        class="mini-day"
        :class="{
          'current-month': day.isCurrentMonth,
          'today': day.isToday,
          'selected': isDateSelected(day.date)
        }"
        @click="selectDate(day.date)"
      >
        {{ day.day }}
      </div>
    </div>
    
    <div class="calendar-actions">
      <button class="action-btn" @click.stop="clearSelection">清除</button>
      <button class="action-btn primary" @click.stop="goToToday">今天</button>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
import { 
  format, 
  addMonths, 
  startOfMonth, 
  endOfMonth, 
  eachDayOfInterval, 
  isSameMonth, 
  isToday, 
  isSameDay,
  addDays,
  getDay,
  parseISO,
  isValid
} from "date-fns";

const props = defineProps({
  visible: Boolean,
  modelValue: [Date, String],
  mode: {
    type: String,
    default: "single"
  }
});

const emit = defineEmits(['update:modelValue', 'apply', 'close']);

const parseDateValue = (value) => {
  if (!value) return null;
  if (value instanceof Date) return value;
  const parsed = parseISO(value);
  return isValid(parsed) ? parsed : null;
};

const currentDate = ref(new Date());
const selectedDate = ref(parseDateValue(props.modelValue));
const calendarRef = ref(null);

watch(() => props.modelValue, (newVal) => {
  const parsed = parseDateValue(newVal);
  if (parsed) {
    selectedDate.value = parsed;
    currentDate.value = parsed;
  }
});

// 修复：完全隔离月份切换事件
const handlePrevMonth = (event) => {
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();
  currentDate.value = addMonths(currentDate.value, -1);
};

const handleNextMonth = (event) => {
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();
  currentDate.value = addMonths(currentDate.value, 1);
};

const goToToday = (event) => {
  event.stopPropagation();
  const today = new Date();
  currentDate.value = today;
  selectedDate.value = today;
  
  const valueToEmit = props.modelValue instanceof Date 
    ? today 
    : today.toISOString();
  emit('update:modelValue', valueToEmit);
  emit('apply');
  closeCalendar();
};

const handleClickOutside = (event) => {
  if (calendarRef.value && !calendarRef.value.contains(event.target)) {
    closeCalendar();
  }
};

watch(() => props.visible, (newVal) => {
  if (newVal) {
    setTimeout(() => {
      document.addEventListener('click', handleClickOutside);
    }, 0);
  } else {
    document.removeEventListener('click', handleClickOutside);
  }
});

const closeCalendar = () => {
  document.removeEventListener('click', handleClickOutside);
  emit('close');
};

onBeforeUnmount(() => {
  document.removeEventListener('click', handleClickOutside);
});

const currentMonthYear = computed(() => format(currentDate.value, "yyyy年MM月"));

const calendarDays = computed(() => {
  const start = startOfMonth(currentDate.value);
  const end = endOfMonth(currentDate.value);
  const firstDayOfWeek = getDay(start);
  const prevMonthDays = firstDayOfWeek;
  const totalDays = 6 * 7;
  const daysInMonth = eachDayOfInterval({ start, end }).length;
  const nextMonthDays = totalDays - daysInMonth - prevMonthDays;
  const calendarStart = addDays(start, -prevMonthDays);
  const calendarEnd = addDays(end, nextMonthDays);

  return eachDayOfInterval({
    start: calendarStart,
    end: calendarEnd,
  }).map(day => ({
    date: day,
    day: format(day, "d"),
    isCurrentMonth: isSameMonth(day, currentDate.value),
    isToday: isToday(day)
  }));
});

const selectDate = (date) => {
  selectedDate.value = date;
  if (props.mode === "single") {
    applySelection();
  }
};

const isDateSelected = (date) => {
  return selectedDate.value && isSameDay(date, selectedDate.value);
};

const clearSelection = () => {
  selectedDate.value = null;
  emit('update:modelValue', null);
};

const applySelection = () => {
  const valueToEmit = props.modelValue instanceof Date 
    ? selectedDate.value 
    : selectedDate.value?.toISOString();
  emit('update:modelValue', valueToEmit);
  emit('apply');
  closeCalendar();
};
</script>

<style scoped>
/* 原有样式完全不变 */
.mini-calendar {
  position: absolute;
  top: 100%;
  left: 0;
  background-color: white;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  margin-top: 5px;
  border: 1px solid #dcdfe6;
}

.mini-calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.mini-calendar-header span {
  font-size: 16px;
  font-weight: 500;
}

.nav-button {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  cursor: pointer;
  color: #666;
  transition: all 0.2s;
  padding: 0;
}

.nav-button:hover {
  background-color: #f5f5f5;
}

.mini-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.mini-day-header {
  text-align: center;
  font-size: 12px;
  color: #666;
  padding: 8px 0;
}

.mini-day {
  text-align: center;
  padding: 8px 0;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.mini-day.current-month {
  background-color: #fff;
  color: #333;
}

.mini-day:not(.current-month) {
  color: #aaa;
}

.mini-day.today {
  background-color: #e6f7ff;
  color: var(--v-theme);
  font-weight: bold;
}

.mini-day.selected {
  background-color: var(--v-theme) !important;
  color: white !important;
  border-radius: 6px !important;
}

.mini-day:hover:not(.selected) {
  background-color: #f5f7fa;
}

.calendar-actions {
  display: flex;
  justify-content: space-between;
  margin-top: 15px;
}

.action-btn {
  padding: 8px 16px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: white;
  color: #606266;
  cursor: pointer;
  transition: all 0.3s;
}

.action-btn.primary {
  background-color: var(--v-theme);
  color: white;
  border-color: var(--v-theme);
}

.action-btn.primary:hover {
  background-color: #66b1ff;
}
</style>